﻿﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Xml.Serialization;
using NewLife.CommonEntity;
using NewLife.Log;
using NewLife.Web;
using XCode;
using XCode.Configuration;

namespace NewsPub
{
    /// <summary>互动交流</summary>
    [ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
    public class Communicate : Communicate<Communicate> { }
    
    /// <summary>互动交流</summary>
    public partial class Communicate<TEntity> : Entity<TEntity> where TEntity : Communicate<TEntity>, new()
    {
        #region 对象操作﻿
        static Communicate()
        {
            // 用于引发基类的静态构造函数，所有层次的泛型实体类都应该有一个
            TEntity entity = new TEntity();
        }

        /// <summary>验证数据，通过抛出异常的方式提示验证失败。</summary>
        /// <param name="isNew"></param>
        public override void Valid(Boolean isNew)
        {
            // 这里验证参数范围，建议抛出参数异常，指定参数名，前端用户界面可以捕获参数异常并聚焦到对应的参数输入框
            //if (String.IsNullOrEmpty(Name)) throw new ArgumentNullException(_.Name, _.Name.DisplayName + "无效！");
            //if (!isNew && ID < 1) throw new ArgumentOutOfRangeException(_.ID, _.ID.DisplayName + "必须大于0！");

            // 建议先调用基类方法，基类方法会对唯一索引的数据进行验证
            base.Valid(isNew);

            // 在新插入数据或者修改了指定字段时进行唯一性验证，CheckExist内部抛出参数异常
            //if (isNew || Dirtys[__.Name]) CheckExist(__.Name);

        }

        ///// <summary>首次连接数据库时初始化数据，仅用于实体类重载，用户不应该调用该方法</summary>
        //[EditorBrowsable(EditorBrowsableState.Never)]
        //protected override void InitData()
        //{
        //    base.InitData();

        //    // InitData一般用于当数据表没有数据时添加一些默认数据，该实体类的任何第一次数据库操作都会触发该方法，默认异步调用
        //    // Meta.Count是快速取得表记录数
        //    if (Meta.Count > 0) return;

        //    // 需要注意的是，如果该方法调用了其它实体类的首次数据库操作，目标实体类的数据初始化将会在同一个线程完成
        //    if (XTrace.Debug) XTrace.WriteLine("开始初始化{0}[{1}]数据……", typeof(TEntity).Name, Meta.Table.DataTable.DisplayName);

        //    var entity = new Communicate();
        //    entity.ReferenceNumber = "abc";
        //    entity.Name = "abc";
        //    entity.Occupation = 0;
        //    entity.Title = "abc";
        //    entity.Content = "abc";
        //    entity.Publishable = true;
        //    entity.CreateTime = DateTime.Now;
        //    entity.Revert = "abc";
        //    entity.RevertTime = DateTime.Now;
        //    entity.Verified = true;
        //    entity.Insert();

        //    if (XTrace.Debug) XTrace.WriteLine("完成初始化{0}[{1}]数据！", typeof(TEntity).Name, Meta.Table.DataTable.DisplayName);
        //}


        ///// <summary>已重载。基类先调用Valid(true)验证数据，然后在事务保护内调用OnInsert</summary>
        ///// <returns></returns>
        //public override Int32 Insert()
        //{
        //    return base.Insert();
        //}

        ///// <summary>已重载。在事务保护范围内处理业务，位于Valid之后</summary>
        ///// <returns></returns>
        //protected override Int32 OnInsert()
        //{
        //    return base.OnInsert();
        //}
        #endregion

        #region 扩展属性﻿
        /// <summary>显示页地址</summary>
        [DisplayName("显示页地址")]
        [Description("显示页地址")]
        public string ViewUrl
        {
            get { return XTLCMS.CMS.SysModel.FindByID(NewsPub.Classis.FindByID(this._ClassisID).SysModel).ViewUrl; }
        }
        /// <summary>列表页地址</summary>
        [DisplayName("列表页地址")]
        [Description("列表页地址")]
        public string ListUrl
        {
            get { return XTLCMS.CMS.SysModel.FindByID(NewsPub.Classis.FindByID(this._ClassisID).SysModel).ListUrl; }
        }
        public string occupation
        {
            get { return NewsPub.Occupation.FindByID(this._Occupation).Name; }
        }
        public bool isAdmin
        {
            get
            {
                return ManageProvider.Provider.Current.IsAdmin;
                
            }
        }
        [NonSerialized]
        private Classis _Classis;
        /// <summary>该文章所对应的文章分类</summary>
        [XmlIgnore]
        public Classis Classis
        {
            get
            {
                if (_Classis == null && ClassisID > 0 && !Dirtys.ContainsKey("Classis"))
                {
                    _Classis = Classis.FindByID(ClassisID);
                    Dirtys["Classis"] = true;
                }
                return _Classis;
            }
            set { _Classis = value; }
        }

        /// <summary>该文章所对应的文章分类名称</summary>
        [XmlIgnore]
        public String ClassisName { get { return Classis != null ? Classis.Name : null; } }
        #endregion

        #region 扩展查询﻿
        /// <summary>根据编号查找</summary>
        /// <param name="id">编号</param>
        /// <returns></returns>
        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public static TEntity FindByID(Int32 id)
        {
            if (Meta.Count >= 1000)
                return Find(_.ID, id);
            else // 实体缓存
                return Meta.Cache.Entities.Find(_.ID, id);
            // 单对象缓存
            //return Meta.SingleCache[id];
        }
        /// <summary>根据文章分类查找</summary>
        /// <param name="classisid">文章分类</param>
        /// <returns></returns>
        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public static EntityList<TEntity> FindAllByClassisID(Int32 classisid)
        {
            if (Meta.Count >= 1000)
                return FindAll(_.ClassisID, classisid);
            else // 实体缓存
                return Meta.Cache.Entities.FindAll(_.ClassisID, classisid);
        }
        /// <summary>根据咨询编号查找</summary>
        /// <param name="rn">咨询编号</param>
        /// <returns></returns>
        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public static TEntity FindByReferenceNumber(string rn)
        {
            if (Meta.Count >= 1000)
                return Find(_.ReferenceNumber, rn);
            else // 实体缓存
                return Meta.Cache.Entities.Find(_.ReferenceNumber, rn);
            // 单对象缓存
            //return Meta.SingleCache[id];
        }
        #endregion

        #region 高级查询
        // 以下为自定义高级查询的例子

        /// <summary>
        /// 查询满足条件的记录集，分页、排序
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="orderClause">排序，不带Order By</param>
        /// <param name="startRowIndex">开始行，0表示第一行</param>
        /// <param name="maximumRows">最大返回行数，0表示所有行</param>
        /// <returns>实体集</returns>
        [DataObjectMethod(DataObjectMethodType.Select, true)]
        public static EntityList<TEntity> SearchList(String key, String orderClause, Int32 startRowIndex, Int32 maximumRows)
        {
            return FindAll(SearchWhere(key), orderClause, null, startRowIndex, maximumRows);
        }

        /// <summary>
        /// 查询满足条件的记录总数，分页和排序无效，带参数是因为ObjectDataSource要求它跟Search统一
        /// </summary>
        /// <param name="key">关键字</param>
        /// <param name="orderClause">排序，不带Order By</param>
        /// <param name="startRowIndex">开始行，0表示第一行</param>
        /// <param name="maximumRows">最大返回行数，0表示所有行</param>
        /// <returns>记录数</returns>
        public static Int32 SearchListCount(String key, String orderClause, Int32 startRowIndex, Int32 maximumRows)
        {
            return FindCount(SearchWhere(key), null, null, 0, 0);
        }

        /// <summary>构造搜索条件</summary>
        /// <param name="key">关键字</param>
        /// <returns></returns>
        private static String SearchWhere(String key)
        {
            // WhereExpression重载&和|运算符，作为And和Or的替代
            // SearchWhereByKeys系列方法用于构建针对字符串字段的模糊搜索
            //var exp = SearchWhereByKeys(key, null);
            Classis cl = Classis.FindByID(int.Parse(key));

            var exp = _.ClassisID == key;
            if (cl.AllChildKeyString != null)
            {
                foreach (Classis tmp in cl.AllChilds)
                {
                    exp |= _.ClassisID == tmp.ID;
                }
            }
            exp &= _.Publishable == true;
            exp &= _.Verified == true;
            // 以下仅为演示，Field（继承自FieldItem）重载了==、!=、>、<、>=、<=等运算符（第4行）
            //if (userid > 0) exp &= _.OperatorID == userid;
            //if (isSign != null) exp &= _.IsSign == isSign.Value;
            //if (start > DateTime.MinValue) exp &= _.OccurTime >= start;
            //if (end > DateTime.MinValue) exp &= _.OccurTime < end.AddDays(1).Date;

            return exp;
        }
        #endregion

        #region 扩展操作
        #endregion

        #region 业务
        #endregion
    }
}